package yzrilyzr.simplesynth.app;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Fragment;
import android.app.FragmentManager;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Toast;
import android.widget.ToggleButton;

import java.util.HashMap;

import yzrilyzr.simplesynth.app.fragment.PianoKeyboardFragment;
import yzrilyzr.simplesynth.app.view.KeyboardCallback;
import yzrilyzr.simplesynth.app.view.SimpleKeyboardView;
import yzrilyzr.util.MIDIFile;

public class KeyBoardActivity extends Activity implements KeyboardCallback{
	// MIDI事件类型
	private static final int NOTE_ON=0x90;
	private static final int NOTE_OFF=0x80;
	private static final int NOTE_PRESSURE=0xA0;
	private static final int CONTROL_CHANGE=0xB0;
	private static final int PROGRAM_CHANGE=0xC0;
	private int channelID=0;
	// 延音踏板控制号
	// 当前八度
	private final int currentC=36;
	// 延音踏板状态
	private final boolean sustainPedal=false;
	// 当前映射方式
	private final int mappingMode=0; // 0:EveryonePiano, 1:FL Studio, 2:Full Octave
	private SimpleKeyboardView simpleKeyboardView;
	private SharedPreferences sp;
	// 添加键盘样式常量
	private static final int KEYBOARD_STYLE_SIMPLE=0;
	private static final int KEYBOARD_STYLE_PIANO=1;
	private int currentKeyboardStyle=KEYBOARD_STYLE_SIMPLE; // 当前键盘样式
	private final HashMap<Integer,Integer> keyMapping=new HashMap<>();
	@Override
	protected void onCreate(Bundle savedInstanceState){
		super.onCreate(savedInstanceState);
		sp=getSharedPreferences("KeyboardActivityConfig",MODE_PRIVATE);
		// 从SharedPreferences加载键盘样式
		currentKeyboardStyle=sp.getInt("KeyboardStyle",KEYBOARD_STYLE_SIMPLE);
		getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.keyboardactivity);
		simpleKeyboardView=findViewById(R.id.keyboardactivitySimpleKeyboard);
		simpleKeyboardView.setKeyboardCallback(this);
		FragmentManager fm=getFragmentManager();
		PianoKeyboardFragment pianoFragment=(PianoKeyboardFragment)fm.findFragmentById(R.id.keyboardactivityPianoKeyboard);
		pianoFragment.kb1.setKeyboardCallback(this);
		pianoFragment.kb2.setKeyboardCallback(this);
		eopMapping();
		updateKeyboardStyle();
	}
	private void updateKeyboardStyle(){
		FragmentManager fm=getFragmentManager();
		Fragment pianoFragment=fm.findFragmentById(R.id.keyboardactivityPianoKeyboard);
		if(currentKeyboardStyle==KEYBOARD_STYLE_SIMPLE){
			simpleKeyboardView.setVisibility(View.VISIBLE);
			if(pianoFragment!=null){
				fm.beginTransaction().hide(pianoFragment).commit();
			}
		}
		else{
			simpleKeyboardView.setVisibility(View.GONE);
			if(pianoFragment!=null){
				fm.beginTransaction().show(pianoFragment).commit();
			}
		}
	}
	private void eopMapping(){
		keyMapping.clear();
		//0
		keyMapping.put(KeyEvent.KEYCODE_Z,0);
		keyMapping.put(KeyEvent.KEYCODE_X,2);
		keyMapping.put(KeyEvent.KEYCODE_C,4);
		keyMapping.put(KeyEvent.KEYCODE_V,5);
		keyMapping.put(KeyEvent.KEYCODE_B,7);
		keyMapping.put(KeyEvent.KEYCODE_N,9);
		keyMapping.put(KeyEvent.KEYCODE_M,11);
		keyMapping.put(KeyEvent.KEYCODE_COMMA,12);
		keyMapping.put(KeyEvent.KEYCODE_PERIOD,14);
		keyMapping.put(KeyEvent.KEYCODE_SLASH,16);
		//12
		keyMapping.put(KeyEvent.KEYCODE_A,12);
		keyMapping.put(KeyEvent.KEYCODE_S,14);
		keyMapping.put(KeyEvent.KEYCODE_D,16);
		keyMapping.put(KeyEvent.KEYCODE_F,17);
		keyMapping.put(KeyEvent.KEYCODE_G,19);
		keyMapping.put(KeyEvent.KEYCODE_H,21);
		keyMapping.put(KeyEvent.KEYCODE_J,23);
		keyMapping.put(KeyEvent.KEYCODE_K,24);
		keyMapping.put(KeyEvent.KEYCODE_L,26);
		keyMapping.put(KeyEvent.KEYCODE_SEMICOLON,28);
		keyMapping.put(KeyEvent.KEYCODE_APOSTROPHE,29);
		//14
		keyMapping.put(KeyEvent.KEYCODE_Q,24);
		keyMapping.put(KeyEvent.KEYCODE_W,26);
		keyMapping.put(KeyEvent.KEYCODE_E,28);
		keyMapping.put(KeyEvent.KEYCODE_R,29);
		keyMapping.put(KeyEvent.KEYCODE_T,31);
		keyMapping.put(KeyEvent.KEYCODE_Y,33);
		keyMapping.put(KeyEvent.KEYCODE_U,35);
		keyMapping.put(KeyEvent.KEYCODE_I,36);
		keyMapping.put(KeyEvent.KEYCODE_O,38);
		keyMapping.put(KeyEvent.KEYCODE_P,40);
		keyMapping.put(KeyEvent.KEYCODE_LEFT_BRACKET,41);
		keyMapping.put(KeyEvent.KEYCODE_RIGHT_BRACKET,43);
		//21
		keyMapping.put(KeyEvent.KEYCODE_1,36);
		keyMapping.put(KeyEvent.KEYCODE_2,38);
		keyMapping.put(KeyEvent.KEYCODE_3,40);
		keyMapping.put(KeyEvent.KEYCODE_4,41);
		keyMapping.put(KeyEvent.KEYCODE_5,43);
		keyMapping.put(KeyEvent.KEYCODE_6,45);
		keyMapping.put(KeyEvent.KEYCODE_7,47);
		keyMapping.put(KeyEvent.KEYCODE_8,48);
		keyMapping.put(KeyEvent.KEYCODE_9,50);
		keyMapping.put(KeyEvent.KEYCODE_0,52);
		keyMapping.put(KeyEvent.KEYCODE_MINUS,53);
		keyMapping.put(KeyEvent.KEYCODE_EQUALS,55);
	}
	@Override
	public boolean onKeyDown(int keyCode,KeyEvent event){
		if(event.getRepeatCount()>0) return true;
		Integer note=keyMapping.get(keyCode);
		if(note!=null){
			note+=currentC;
			NativePlayer.postEvent(NOTE_ON|channelID,note,127); // 力度127
			return true;
		}
		// 处理八度切换
		if(keyCode==KeyEvent.KEYCODE_VOLUME_UP){
			//currentOctave=Math.min(8,currentOctave+1);
			//Toast.makeText(this,"八度: "+currentOctave,Toast.LENGTH_SHORT).show();
			return true;
		}
		else if(keyCode==KeyEvent.KEYCODE_VOLUME_DOWN){
			//currentOctave=Math.max(0,currentOctave-1);
			//Toast.makeText(this,"八度: "+currentOctave,Toast.LENGTH_SHORT).show();
			return true;
		}
		return super.onKeyDown(keyCode,event);
	}
	@Override
	public boolean onKeyUp(int keyCode,KeyEvent event){
		Integer note=keyMapping.get(keyCode);
		if(note!=null){
			note+=currentC;
			if(!sustainPedal){
				NativePlayer.postEvent(NOTE_OFF|channelID,note,0);
			}
			return true;
		}
		return super.onKeyUp(keyCode,event);
	}
	public void sustain(View v){
		boolean sus=((ToggleButton)v).isChecked();
		NativePlayer.postEvent(CONTROL_CHANGE|channelID,MIDIFile.CC.SUSTAIN_SWITCH,sus?127:0);
	}
	int selectedProgram=0;
	public void programChange(View view){
		// 创建对话框构建器
		AlertDialog.Builder builder=new AlertDialog.Builder(this);
		builder.setTitle("选择MIDI乐器");
		// 创建0-127的数字数组
		String[] programs=new String[128];
		String[] instrumentNames=getResources().getStringArray(R.array.midi_instrument_names);
		for(int i=0;i<128;i++){
			programs[i]=i+": "+(i<instrumentNames.length?instrumentNames[i]:"Unknown");
		}
		// 设置单选列表
		builder.setSingleChoiceItems(programs,selectedProgram,new DialogInterface.OnClickListener(){
			@Override
			public void onClick(DialogInterface dialog,int which){
				// 用户选择后立即发送MIDI事件并关闭对话框
				// 确保程序号在有效范围内
				if(which<0||which>127){
					return;
				}
				selectedProgram=which;
				// 发送MIDI程序改变事件
				NativePlayer.postEvent(PROGRAM_CHANGE|channelID,which,0);
				// 可选：显示Toast通知
				Toast.makeText(KeyBoardActivity.this,"选择MIDI乐器: "+which,Toast.LENGTH_SHORT)
					 .show();
				dialog.dismiss();
			}
		});
		// 添加取消按钮
		builder.setNegativeButton(R.string.cancel,new DialogInterface.OnClickListener(){
			@Override
			public void onClick(DialogInterface dialog,int which){
				dialog.dismiss();
			}
		});
		// 创建并显示对话框
		AlertDialog dialog=builder.create();
		dialog.show();
	}
	public void keyBoardStyle(View view){
		AlertDialog.Builder builder=new AlertDialog.Builder(this);
		builder.setTitle("键盘样式选择");
		String[] programs=new String[]{"简单","钢琴键盘"};
		int selectedStyle=sp.getInt("KeyboardStyle",KEYBOARD_STYLE_SIMPLE);
		builder.setSingleChoiceItems(programs,selectedStyle,new DialogInterface.OnClickListener(){
			@Override
			public void onClick(DialogInterface dialog,int which){
				currentKeyboardStyle=which;
				sp.edit().putInt("KeyboardStyle",which).apply();
				updateKeyboardStyle();
				dialog.dismiss();
			}
		});
		builder.setNegativeButton("返回",new DialogInterface.OnClickListener(){
			@Override
			public void onClick(DialogInterface dialog,int which){
				dialog.dismiss();
			}
		});
		AlertDialog dialog=builder.create();
		dialog.show();
	}
	public void sendToChannel(View view){
		AlertDialog.Builder builder=new AlertDialog.Builder(this);
		builder.setTitle("发送至通道");
		String[] programs=new String[16];
		for(int i=0;i<16;i++){
			programs[i]=String.valueOf(i+1);
		}
		builder.setSingleChoiceItems(programs,channelID,new DialogInterface.OnClickListener(){
			@Override
			public void onClick(DialogInterface dialog,int which){
				if(which>=0&&which<16) channelID=which;
				dialog.dismiss();
			}
		});
		builder.setNegativeButton("返回",new DialogInterface.OnClickListener(){
			@Override
			public void onClick(DialogInterface dialog,int which){
				dialog.dismiss();
			}
		});
		AlertDialog dialog=builder.create();
		dialog.show();
	}
	@Override
	public void noteOn(int id,int vel){
		NativePlayer.postEvent(NOTE_ON|channelID,id,vel);
	}
	@Override
	public void noteOff(int id){
		NativePlayer.postEvent(NOTE_OFF|channelID,id,0);
	}
	@Override
	public void notePressure(int id,int vel){
		NativePlayer.postEvent(NOTE_PRESSURE|channelID,id,vel);
	}
}
